#pragma once

namespace hHashVectorDetail
{
	template <typename Val, bool IsConst>
	class Iterator
	{
		friend hHashVector<Val>;
		friend Node<Val>;

		using Vec = std::conditional_t<IsConst, const hHashVector<Val>, hHashVector<Val>>;
		using Node = std::conditional_t<IsConst, const Node<Val>, Node<Val>>;
		using PNodePtr = std::shared_ptr<Node*>;
		using ValRef = std::reference_wrapper<std::conditional_t<IsConst, const Val, Val>>;
		using CValRef = std::reference_wrapper<const Val>;
		using RetPr = std::pair<size_t, ValRef>;
		using CRetPr = std::pair<size_t, CValRef>;

		PNodePtr _ppNode;
	public:
		Iterator(PNodePtr ppNode = PNodePtr()) : _ppNode(ppNode) {}
		auto operator->()->std::shared_ptr<RetPr>;
		auto operator->() const->std::shared_ptr<CRetPr>;
		auto operator*()->RetPr;
		auto operator++()->Iterator&;
		auto operator++(int)->Iterator;

		bool operator==(const Iterator& other) const;
		bool operator!=(const Iterator& other) const { return !(*this == other); }
		operator bool() const;

		auto& get() { return _ppNode; }
	};
}